/*
 * ValueImpl.cpp
 *
 *  Created on: 2009-11-24
 *      Author: ws
 */

#include"Value.hpp"
#include"Region.hpp"
#include"DUChain.hpp"

static std::string get_core_name(enum Core c)
{
	switch(c)
	{
	case NO_CORE:
		return "NO_CORE";
	case CORE_X:
		return "CORE_X";
	case CORE_Y:
		return "CORE_Y";
	case CORE_Z:
		return "CORE_Z";
	case CORE_T:
		return "CORE_T";
	case MU_U:
		return "MU_U";
	case MU_V:
		return "MU_V";
	case MU_W:
		return "MU_W";
	default:
		assert("Core_Name: unexpected core type");
	}
}

#define CAST_TEMPLATE(XXXValue, XXX_VT) \
XXXValue* XXXValue##_cast(Value* v)\
{\
	if(XXX_VT & v->get_type())\
		return (XXXValue*)v;\
	else\
		return NULL;\
}

#define CONST_CAST_TEMPLATE(XXXValue, XXX_VT) \
XXXValue const * XXXValue##_cast(Value const *v) \
{\
	if(XXX_VT & v->get_type())\
		return (XXXValue const *) v;\
	else\
		return NULL;\
}

CAST_TEMPLATE(RegValue, REG_VT)
CONST_CAST_TEMPLATE(RegValue , REG_VT);

CAST_TEMPLATE(MacroValue, MACRO_VT)
CONST_CAST_TEMPLATE(MacroValue, MACRO_VT)

CAST_TEMPLATE(GenValue, GEN_VT)
CONST_CAST_TEMPLATE(GenValue, GEN_VT)

CAST_TEMPLATE(ConstValue, CONST_VT)
CONST_CAST_TEMPLATE(ConstValue, CONST_VT)

CAST_TEMPLATE(LabelValue, LABEL_VT)
CONST_CAST_TEMPLATE(LabelValue, LABEL_VT)


CAST_TEMPLATE(ImmValue, IMM_VT)
CONST_CAST_TEMPLATE(ImmValue, IMM_VT)

CAST_TEMPLATE(BBValue, BB_VT)
CONST_CAST_TEMPLATE(BBValue, BB_VT)

bool operator == (const Value &x, const Value &y)
{
	if(x.get_type() == y.get_type())
	{
		switch (x.get_type())
		{
		case MACRO_VT:
		{
			const MacroValue * a = MacroValue_cast(&x);
			const MacroValue * b = MacroValue_cast(&x);
			assert(a != NULL);	
			assert(b != NULL);
			return ( a->id == b->id);
		}
		case LABEL_VT:
		{
			const LabelValue *a = LabelValue_cast(&x);
			const LabelValue *b = LabelValue_cast(&y); 
			assert(a != NULL);
			assert(b != NULL);
			return (a->id == b->id);
		}
		case IMM_VT:
		{
			const ImmValue* a = ImmValue_cast(&x);
			const ImmValue* b = ImmValue_cast(&y);
			assert(a!= NULL);
			assert(b!= NULL);
			return (a->id == b->id);
		}
		case CTR_FLOW_VT:
		{
			return true;
		}
		case MEM_VT:
		{
			return true;
		}
		default:
		{
			assert("error" == " type of value is not expected");
		}
		}
	}
}

bool operator != (const Value &x, const Value &y)
{
	return (! (x == y));
}

void GenValue::assign_physical_register(enum TargetInfo::PhysicalRegister physical_register)
{
	assert(core == TargetInfo::T_get_core( physical_register));
	this->physical_register = physical_register;
}

void MacroValue::assign_physical_register(enum TargetInfo::PhysicalRegister physical_register)
{
	assert(physical_register == M_get_macro_physical_register((enum MACRO_ID) id));	
}
void RegValue::build_du_chain(DUChain * chain)
{
	assert(du_chain == NULL);
	assert(chain->get_id() == id);
	du_chain = chain;
}
